package cn.lili.modules.member.serviceimpl;

import cn.lili.common.enums.ResultCode;
import cn.lili.common.exception.ServiceException;
import cn.lili.common.security.context.UserContext;
import cn.lili.common.security.enums.SceneEnums;
import cn.lili.common.vo.PageVO;
import cn.lili.modules.member.entity.dos.UserAddress;
import cn.lili.modules.member.entity.dto.AddressSearchParams;
import cn.lili.modules.member.entity.enums.AddressTypeEnum;
import cn.lili.modules.member.mapper.UserAddressMapper;
import cn.lili.modules.member.service.UserAddressService;
import cn.lili.mybatis.util.PageUtil;
import cn.lili.mybatis.util.SceneHelp;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.apache.shardingsphere.transaction.annotation.ShardingTransactionType;
import org.apache.shardingsphere.transaction.core.TransactionType;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Objects;

/**
 * 收货地址业务层实现
 *
 * @author Chopper
 * @since 2020/11/18 9:44 上午
 */
@Service
public class UserAddressServiceImpl extends ServiceImpl<UserAddressMapper, UserAddress> implements UserAddressService {

    @Override
    public Page<UserAddress> addressPage(PageVO page, AddressSearchParams addressSearchParams) {
        return this.page(PageUtil.initPage(page), addressSearchParams.queryWrapper());
    }

    @Override
    public Page<UserAddress> addressPageNoAuth(PageVO page, AddressSearchParams addressSearchParams) {
        return this.page(PageUtil.initPage(page), addressSearchParams.queryWrapperNoAuth());
    }

    @Override
    public UserAddress getAddressByMember(AddressSearchParams addressSearchParams) {
        List<UserAddress> userAddresses = this.list(addressSearchParams.queryWrapper());
        if (userAddresses == null || userAddresses.isEmpty()) {
            throw new ServiceException(ResultCode.ADDRESS_UN_SETTING);
        }
        return userAddresses.get(0);
    }

    @Override
    public UserAddress getUserAddressNoAuth(AddressSearchParams addressSearchParams) {
        List<UserAddress> userAddresses = this.list(addressSearchParams.queryWrapperNoAuth());
        if (userAddresses == null || userAddresses.isEmpty()) {
            throw new ServiceException(ResultCode.ADDRESS_UN_SETTING);
        }
        for (UserAddress userAddress : userAddresses) {
            if (Boolean.TRUE.equals(userAddress.getIsDefault())) {
                return userAddress;
            }
        }
        return userAddresses.get(0);
    }

    @Override
    public UserAddress getUserAddress(String id) {
        QueryWrapper<UserAddress> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("id", id);
        //管理员查看，则忽略用户id参数条件
        if (!Objects.requireNonNull(UserContext.getCurrentUser()).getScene().equals(SceneEnums.MANAGER)) {
            queryWrapper.eq("extend_id", UserContext.getCurrentUser().getExtendId());
        }
        return this.getOne(queryWrapper);
    }

    /**
     * 根据地址ID获取当前用户地址信息
     *
     * @param userId 当前用户Id
     * @return 当前用户的地址信息
     */
    @Override
    public UserAddress getUserDefaultAddress(String userId) {

        //如果不是管理员请求，将用户id置为当前token中的信息id
        if (!Objects.requireNonNull(UserContext.getCurrentUser()).getScene().equals(SceneEnums.MANAGER)) {
            userId = UserContext.getCurrentUser().getExtendId();
        }

        QueryWrapper<UserAddress> queryWrapper = new QueryWrapper<UserAddress>()
                .eq("extend_id", userId)
                .eq("type", AddressTypeEnum.RECEIVE.name())
                .eq("is_default", true);

        if (this.count(queryWrapper) > 1) {
            UpdateWrapper<UserAddress> updateWrapper = new UpdateWrapper<>();
            updateWrapper.set("is_default", false)
                    .eq("extend_id", userId)
                    .eq("type", AddressTypeEnum.RECEIVE.name());
            this.update(updateWrapper);
            return null;
        } else {
            return this.getOne(queryWrapper);
        }
    }

    @Override
    @Transactional
    @ShardingTransactionType(TransactionType.BASE)
    public UserAddress saveUserAddress(UserAddress userAddress) {

        //判断当前地址是否为默认地址，如果为默认需要将其他的地址修改为非默认
        if (Boolean.TRUE.equals(userAddress.getIsDefault())) {
            removeDefaultAddress(userAddress);
        }
        //添加用户地址
        this.save(userAddress);

        return userAddress;
    }

    @Override
    @Transactional
    public UserAddress updateUserAddress(UserAddress userAddress) {
        //获取原始地址信息
        UserAddress originalUserAddress = this.getUserAddress(userAddress.getId());

        if (originalUserAddress != null) {

            if (userAddress.getIsDefault() == null) {
                userAddress.setIsDefault(false);
            } else if (Boolean.TRUE.equals(userAddress.getIsDefault())) {
                //判断当前地址是否为默认地址，如果为默认需要将其他的地址修改为非默认
                removeDefaultAddress(userAddress);
            }

            this.saveOrUpdate(userAddress);
        } else {
            throw new ServiceException(ResultCode.USER_AUTHORITY_ERROR);
        }

        return userAddress;
    }

    @Override
    @Transactional
    @ShardingTransactionType(TransactionType.BASE)
    public boolean removeUserAddress(String id) {
        QueryWrapper<UserAddress> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("id", id);
        //管理员查看，则忽略用户id参数条件
        SceneHelp.queryHandler(queryWrapper, true);

        return this.remove(queryWrapper);
    }

    @Override
    public void updateDefaultAddress(String addressId) {
        UserAddress userAddress = this.getUserAddress(addressId);
        if (userAddress != null) {
            //判断当前地址是否为默认地址，如果为默认需要将其他的地址修改为非默认
            removeDefaultAddress(userAddress);
            //将当前地址修改为默认地址
            UpdateWrapper<UserAddress> updateWrapper = new UpdateWrapper<>();
            updateWrapper.set("is_default", true);
            updateWrapper.eq("id", addressId);
            this.update(updateWrapper);
        } else {
            throw new ServiceException(ResultCode.USER_AUTHORITY_ERROR);
        }
    }

    /**
     * 修改用户默认收件地址
     *
     * @param userAddress 收件地址
     */
    private void removeDefaultAddress(UserAddress userAddress) {

        //将用户的地址修改为非默认地址
        UpdateWrapper<UserAddress> updateWrapper = new UpdateWrapper<>();
        updateWrapper.set("is_default", false);

        // 根据用户id以及地址类型进行过滤， 写入默认值为false
        updateWrapper.eq("is_default", true);
        updateWrapper.eq("type", userAddress.getType());
        updateWrapper.eq("extend_id", userAddress.getExtendId());
        updateWrapper.eq("scene", userAddress.getScene());

        this.update(updateWrapper);
    }
}